﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using BLL_Library;

namespace RecipeCollection
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        /// <summary>
        /// Managerklassen
        /// </summary>
        private RecipesMngr m_recipesMngr;

        /// <summary>
        /// Recipeklassen
        /// </summary>
        private Recipe m_currentNewRecipe;

        /// <summary>
        /// Lista för sökning
        /// </summary>
        private List<Recipe> m_recipeList;
        /// <summary>
        /// Standardkonstruktor
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
            m_recipesMngr = new RecipesMngr();
            ResetRecipe();
            m_recipeList = null;

            // Laddar alla listor m.m
            InitializeComponents();
        }

        /// <summary>
        /// Skapar all information i comboboxar osv
        /// </summary>
        private void InitializeComponents()
        {

            // Laddar recept från fil
            try
            {
                m_recipesMngr.LoadRecipes();
            }
            catch (Exception)
            {
            }


            // Fyller comboboxar
            ComboBoxAddRecipeType.ItemsSource = Enum.GetValues(typeof(RecipeType)).Cast<RecipeType>();
            ComboBoxAddMeasure.ItemsSource = Enum.GetValues(typeof(MeasureType)).Cast<MeasureType>();
            ComboBoxEditRecipeType.ItemsSource = Enum.GetValues(typeof(RecipeType)).Cast<RecipeType>();
            ComboBoxEditMeasure.ItemsSource = Enum.GetValues(typeof(MeasureType)).Cast<MeasureType>();
            ComboboxSearchAlt.ItemsSource = Enum.GetValues(typeof(SearchType)).Cast<SearchType>();
            ComboboxSearchAlt.SelectedIndex = 0;

            // Fyller alla ListViews
            UpdateListViews();

            for (int i = 1; i < 12; i++)
			{
                if (i == 11)
                {
                    ComboBocAddNumberOfPortions.Items.Add("10+");
                    ComboBocEditNumberOfPortions.Items.Add("10+");
                }
                else
                {
                    ComboBocAddNumberOfPortions.Items.Add(i);
                    ComboBocEditNumberOfPortions.Items.Add(i);
                }
			}

            // Sätter alla combooxar selectedindex default värde;
            ResetComboBoxes();
        }

        /// <summary>
        /// Uppdaterar alla ListView, tex efter redigering
        /// </summary>
        private void UpdateListViews()
        {
            // Tömmmer alla
            ListViewEditRecipe.Items.Clear();

            // Fyller alla ListViews
            List<Recipe> recipeList = m_recipesMngr.GetRecipes();
            for (int i = 0; i < recipeList.Count(); i++)
            {
                ListViewEditRecipe.Items.Add(recipeList[i]);
            }
        }

        /// <summary>
        /// Lägg till recept knapp nedtryckt
        /// </summary>
        private void ButtonAddNewRecipeOnClick(object sender, RoutedEventArgs e)
        {
            ResetRecipe();

            // Validering
            int error = -1;
            try
            {
                error = ValidateRecipeInput(ComboBoxAddRecipeType.SelectedIndex, TextBoxAddRecipeName.Text, ComboBocAddNumberOfPortions.SelectedIndex, ListViewAddIngredients.Items.Count, TextBoxAddDescription.Text);
            }
            catch (RecipeNameException)
            {
                TextBoxAddRecipeName.Focus();
            }
            catch (RecipeTypeExeption)
            {
            }
            catch (RecipePortionsExeption)
            {
            }
            catch (RecipeDescriptionExeption)
            {
                TextBoxAddDescription.Focus();
            }
            
            if (error == 0)
            {
                // Fyller objektet
                m_currentNewRecipe.Name = TextBoxAddRecipeName.Text;
                m_currentNewRecipe.RecipeType = (RecipeType)ComboBoxAddRecipeType.SelectedIndex;
                m_currentNewRecipe.Portions = (int)ComboBocAddNumberOfPortions.Items[ComboBocAddNumberOfPortions.SelectedIndex];
                m_currentNewRecipe.Id = m_recipesMngr.GetRecipes().Count();
                m_currentNewRecipe.Description = TextBoxAddDescription.Text;
                for (int i = 0; i < ListViewAddIngredients.Items.Count; i++)
                {
                    Ingredient ing = new Ingredient();
                    ing.MeasureType = ((Ingredient)ListViewAddIngredients.Items[i]).MeasureType;
                    ing.Name = ((Ingredient)ListViewAddIngredients.Items[i]).Name;
                    ing.Quantity = ((Ingredient)ListViewAddIngredients.Items[i]).Quantity;

                    m_currentNewRecipe.Ingredients.Add(ing);
                }

                m_recipesMngr.Add(m_currentNewRecipe);

                // Uppdatera ListViews
                UpdateListViews();

                // Rensar alla textboxar m.m
                TextBoxAddRecipeName.Text = "";
                TextBoxAddNumberOfIngredients.Text = "";
                TextBoxAddIngredientName.Text = "";
                TextBoxAddDescription.Text = "";
                ResetComboBoxes();
                ListViewAddIngredients.Items.Clear();

                // Spara receptet till fil
                m_recipesMngr.SaveRecipes();

                // Nollställer variabler
                ResetRecipe();
            }
        }

        /// <summary>
        /// Nollställer medlemsvariablen
        /// </summary>
        private void ResetRecipe()
        {
            // Nollställer medlemsvariabler
            m_currentNewRecipe = new Recipe();
        }

        /// <summary>
        /// Återstälelr alla comboboxar till selectedindex 0
        /// </summary>
        private void ResetComboBoxes()
        {
            ComboBoxAddRecipeType.SelectedIndex = 0;
            ComboBocAddNumberOfPortions.SelectedIndex = 0;
            ComboBoxAddMeasure.SelectedIndex = 0;
            ComboBoxEditMeasure.SelectedIndex = 0;
            ComboBoxEditRecipeType.SelectedIndex = 0;
            ComboBocEditNumberOfPortions.SelectedIndex = 0;
        }

        /// <summary>
        /// Validera indatan
        /// </summary> 
        private int ValidateRecipeInput(int typeSelectedIndex, string nameText, int nrPortionsSelectedIndex, int nrOfIngredients, string description)
        {
            if (typeSelectedIndex == -1)
            {
                MessageBox.Show("Recepttyp måste anges, vänligen försök igen!");
                throw new RecipeTypeExeption();
            }
            else if (String.IsNullOrWhiteSpace(nameText))
            {
                MessageBox.Show("Receptnamn måste anges, vänligen försök igen!");
                throw new RecipeNameException();
            }
            else if (nrPortionsSelectedIndex == -1)
            {
                MessageBox.Show("Antal portioner måste anges, vänligen försök igen!");
                throw new RecipePortionsExeption();
            }
            else if (nrOfIngredients == 0)
            {
                MessageBox.Show("Minst 1 ingrediens måste anges, vänligen försök igen!");
                throw new RecipePortionsExeption();
            }
            else if (String.IsNullOrWhiteSpace(description))
            {
                MessageBox.Show("Måste finnas en beskrivning, vänligen försök igen");
                throw new RecipeDescriptionExeption();
            }

            return 0;
        }

        /// <summary>
        ///  Validera indatan
        /// </summary>
        private bool ValidateIngredientInput(string ingName, string nrOfInredients, int measureSelectedIndex)
        {
            if (String.IsNullOrWhiteSpace(ingName))
            {
                MessageBox.Show("Ett namn på ingrediensen måste anges, vänligen försök igen!");
                return false;
            }
            if (!String.IsNullOrWhiteSpace(ingName) && String.IsNullOrWhiteSpace(nrOfInredients))
            {
                MessageBox.Show("Ett antal av ingrediensen måste anges, vänligen försök igen!");
                return false;
            }
            if (measureSelectedIndex == -1)
            {
                MessageBox.Show("Måttyp måste anges, vänligen försök igen!");
            }
            try
            {
                int number = int.Parse(nrOfInredients);
                if (number < 0)
                {
                    MessageBox.Show("Antal ingredienser måste vara större än 0!");
                    return false;
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Antal ingredienser måste vara ett heltal!");
                return false;
            }            

            return true;
        }

        /// <summary>
        /// Lägg till ingrediens-knapp tryckt
        /// </summary>
        private void ButtonAddIngredientClick(object sender, RoutedEventArgs e)
        {
            int error = 0;
            try 
	        {
                if (String.IsNullOrWhiteSpace(TextBoxAddIngredientName.Text))
                {
                    error = -1;
                    MessageBox.Show("Namnet på ingrediensen måste ha innehåll!");
                    TextBoxAddIngredientName.Focus();
                }
                else if (ComboBoxAddMeasure.SelectedIndex == -1)
                {
                    error = -1;
                    MessageBox.Show("Måste välja mängdtyp");
                }      
		        else if (int.Parse(TextBoxAddNumberOfIngredients.Text) < 0)
                {
                    MessageBox.Show("Antal måste vara ett heltal och större än 0");
                    error = -1;
                    TextBoxAddNumberOfIngredients.Focus();
                }
	        }
	        catch (Exception)
	        {
                error = -1;
                MessageBox.Show("Antal måste vara ett heltal och större än 0");
                TextBoxAddNumberOfIngredients.Focus();
	        }

            if (error == 0)
	        {
		        var ingredient = new Ingredient
                {
                    Name = TextBoxAddIngredientName.Text,
                    Quantity = int.Parse(TextBoxAddNumberOfIngredients.Text),
                    MeasureType = (MeasureType)Enum.Parse(typeof(MeasureType), ComboBoxAddMeasure.SelectedItem.ToString()),
                };

                ListViewAddIngredients.Items.Add(ingredient);

                // Rensa fält
                TextBoxAddIngredientName.Text = "";
                TextBoxAddNumberOfIngredients.Text = "";
                ComboBoxAddMeasure.SelectedIndex = 0;
                TextBoxAddIngredientName.Focus();             
	        }
        }

        /// <summary>
        /// När man byter recept i Redigera
        /// </summary>
        private void ListViewEditRecipeSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // Säkerhets check
            if (ListViewEditRecipe.SelectedIndex != -1)
            {
                // Nollställ listan och rensar boxar m.m
                ListViewEditIngredients.Items.Clear();
                TextBoxEditIngredientName.Text = "";
                TextBoxEditNumberOfIngredients.Text = "";
                ComboBoxEditMeasure.SelectedIndex = -1;

                m_currentNewRecipe = m_recipesMngr.GetRecipe(ListViewEditRecipe.SelectedIndex);
                TextBoxEditDescription.Text = m_currentNewRecipe.Description;
                ComboBoxAddRecipeType.SelectedIndex = (int)m_currentNewRecipe.RecipeType;
                TextBoxEditRecipeName.Text = m_currentNewRecipe.Name;
                ComboBocEditNumberOfPortions.SelectedIndex = (int)m_currentNewRecipe.Portions;
                UpdateIngredientListViews();
            }           
        }

        /// <summary>
        /// Uppdaterar ListView för Ingredienserna
        /// </summary>
        private void UpdateIngredientListViews()
        {
            // Tömmer den först
            ListViewEditIngredients.Items.Clear();

            // Lägger till alla ingredienser
            for (int i = 0; i < m_currentNewRecipe.Ingredients.Count(); i++)
            {
                ListViewEditIngredients.Items.Add(m_currentNewRecipe.Ingredients[i]);
            }
        }

        /// <summary>
        /// Man vill spara ett recept efter redigering
        /// </summary>
        private void ButtonEditSaveRecipeOnClick(object sender, RoutedEventArgs e)
        {
            int error = -1;
            try
            {
                error = ValidateRecipeInput(ComboBoxEditRecipeType.SelectedIndex, TextBoxEditRecipeName.Text, ComboBocEditNumberOfPortions.SelectedIndex, ListViewEditIngredients.Items.Count, TextBoxEditDescription.Text);
            }
            catch (RecipeNameException)
            {
                TextBoxEditRecipeName.Focus();
            }
            catch (RecipeTypeExeption)
            {
            }
            catch (RecipePortionsExeption)
            {
            }
            catch (RecipeDescriptionExeption)
            {
                TextBoxEditDescription.Focus();
            }

            if (error == 0)
            {
                // Fyller objektet
                m_currentNewRecipe.Name = TextBoxEditRecipeName.Text;
                m_currentNewRecipe.RecipeType = (RecipeType)ComboBoxEditRecipeType.SelectedIndex;
                m_currentNewRecipe.Portions = (int)ComboBocEditNumberOfPortions.Items[ComboBocEditNumberOfPortions.SelectedIndex];
                m_currentNewRecipe.Id = m_recipesMngr.GetRecipes().Count();
                m_currentNewRecipe.Description = TextBoxEditDescription.Text;
                for (int i = 0; i < ListViewEditIngredients.Items.Count; i++)
                {
                    Ingredient ing = m_currentNewRecipe.Ingredients[i];
                    ing.MeasureType = ((Ingredient)ListViewEditIngredients.Items[i]).MeasureType;
                    ing.Name = ((Ingredient)ListViewEditIngredients.Items[i]).Name;
                    ing.Quantity = ((Ingredient)ListViewEditIngredients.Items[i]).Quantity;
                }

                // Uppdatera ListViews
                UpdateListViews();

                ResetEditComponents();

                // Sparar till fil
                m_recipesMngr.SaveRecipes();
            }
        }

        /// <summary>
        /// Rensar fält m.m
        /// </summary>
        private void ResetEditComponents()
        {
            // Rensar alla textboxar m.m
            TextBoxEditRecipeName.Text = "";
            TextBoxEditNumberOfIngredients.Text = "";
            TextBoxEditIngredientName.Text = "";
            TextBoxEditDescription.Text = "";
            ResetComboBoxes();
            ListViewEditIngredients.Items.Clear();
        }

        /// <summary>
        /// Användaren har valt en ingrediens i redigera
        /// </summary>
        private void ListViewEditIngredientsSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // Koll om man valt något
            if (ListViewEditIngredients.SelectedIndex != -1)
            {
                Recipe recipe = m_recipesMngr.GetRecipe(ListViewEditRecipe.SelectedIndex);
                Ingredient ing = recipe.Ingredients[ListViewEditIngredients.SelectedIndex];

                // Fyller informationen i boxar m.m
                TextBoxEditIngredientName.Text = ing.Name;
                TextBoxEditNumberOfIngredients.Text = ing.Quantity.ToString();
                ComboBoxEditMeasure.SelectedIndex = (int)ing.MeasureType;
            }
        }

        /// <summary>
        /// Användaren vill ta bort valt recept
        /// </summary>
        private void ButtonEditRemoveOnCLick(object sender, RoutedEventArgs e)
        {
            // Koll
            if (ListViewEditRecipe.SelectedIndex != -1)
            {
                if ((MessageBoxResult)MessageBox.Show("Vill du verkligen ta bort detta recept?", "Ta bort?", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    m_recipesMngr.DeleteRecipe(m_currentNewRecipe.Id);
                    UpdateListViews();
                    ResetEditComponents();

                    // Sparar ändringen
                    m_recipesMngr.SaveRecipes();
                }
                else
                {
                    MessageBox.Show("Du har valt Nej och bortagningen avbröts!");
                }
            }            
        }

        /// <summary>
        /// Användaren vill spara ett redigerat recept
        /// </summary>
        private void ButtonEditIngredientOnClick(object sender, RoutedEventArgs e)
        {
            // Koll
            if (ListViewEditIngredients.SelectedIndex != -1)
            {
                Ingredient ing = m_currentNewRecipe.Ingredients[ListViewEditIngredients.SelectedIndex];
                ing.Name = TextBoxEditIngredientName.Text;
                ing.MeasureType = (MeasureType)ComboBoxEditMeasure.SelectedIndex;
                ing.Quantity = int.Parse(TextBoxEditNumberOfIngredients.Text);

                UpdateIngredientListViews();

                // Rensar fält
                TextBoxEditIngredientName.Text = "";
                TextBoxEditNumberOfIngredients.Text = "";
                ComboBoxEditMeasure.SelectedIndex = -1;

                // Sparar ändringar 
                m_recipesMngr.SaveRecipes();
            }
            
        }

        /// <summary>
        /// Användaren vill ta bort en ingrediens
        /// </summary>
        private void ButtonEditRemoveIngredientOnClick(object sender, RoutedEventArgs e)
        {
            //Koll
            if (ListViewEditIngredients.SelectedIndex != -1)
            {
                if (ListViewEditIngredients.Items.Count > 1)
                {
                    if ((MessageBoxResult)MessageBox.Show("Vill du verkligen ta bort denna ingrediens?", "Ta bort?", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                    {
                        m_currentNewRecipe.Ingredients.RemoveAt(ListViewEditIngredients.SelectedIndex);

                        UpdateIngredientListViews();

                        // Rensar fält
                        TextBoxEditIngredientName.Text = "";
                        TextBoxEditNumberOfIngredients.Text = "";
                        ComboBoxEditMeasure.SelectedIndex = -1;

                        // Sparar ändringar 
                        m_recipesMngr.SaveRecipes();
                    }
                }
                else
                {
                    MessageBox.Show("Det måste finnas minst 1 ingrediens på varje recept!", "Dum Användare, inte göra så!", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                
            }
            else
            {
                MessageBox.Show("Du har valt Nej och bortagningen avbröts!");
            }
        }

        /// <summary>
        /// Användaren vill lägga till en ingrediens i redigera
        /// </summary>
        private void ButtonEditAddIngredientOnClick(object sender, RoutedEventArgs e)
        {
            int error = 0;
            try 
	        {	        
		        if (String.IsNullOrWhiteSpace(TextBoxEditIngredientName.Text))
                {
                    error = -1;
                    MessageBox.Show("Namnet på ingrediensen måste ha innehåll!");
                    TextBoxEditIngredientName.Focus();
                }
                else if (ComboBoxEditMeasure.SelectedIndex == -1)
                {
                    error = -1;
                    MessageBox.Show("Måste välja mängdtyp");
                }      
		        else if (int.Parse(TextBoxEditNumberOfIngredients.Text) < 0)
                {
                    MessageBox.Show("Antal måste vara ett heltal och större än 0");
                    error = -1;
                    TextBoxEditNumberOfIngredients.Focus();
                }
	        }
	        catch (Exception)
	        {
                MessageBox.Show("Antal måste vara ett heltal och större än 0");
                error = -1;
                TextBoxEditNumberOfIngredients.Focus();
	        }

            if (error == 0)
            {
                var ingredient = new Ingredient
                {
                    Name = TextBoxEditIngredientName.Text,
                    Quantity = int.Parse(TextBoxEditNumberOfIngredients.Text),
                    MeasureType = (MeasureType)Enum.Parse(typeof(MeasureType), ComboBoxEditMeasure.SelectedItem.ToString()),
                };

                m_currentNewRecipe.Ingredients.Add(ingredient);

                UpdateIngredientListViews();

                // Rensa fält
                TextBoxEditIngredientName.Text = "";
                TextBoxEditNumberOfIngredients.Text = "";
                ComboBoxEditMeasure.SelectedIndex = 0;
                TextBoxEditIngredientName.Focus();

                // Sparar ändringar
                m_recipesMngr.SaveRecipes();
            }
        }
        /// <summary>
        /// Knapptryck för att aktivera sökningen av recept
        /// </summary>
        private void ButtonSearch_Click(object sender, RoutedEventArgs e)
        {
            if (ComboboxSearchAlt.SelectedIndex == 1) // Sök på namn
            {
                m_recipesMngr.SetSearchMethod(new NameSearch(m_recipesMngr.GetRecipes(), TextboxSearch.Text));
            }

            else // Sökning baserat på ingrediens
            {
                m_recipesMngr.SetSearchMethod(new IngredientSearch(m_recipesMngr.GetRecipes(), TextboxSearch.Text));
            }

            var tempList = m_recipesMngr.GetRecipes();
            m_recipeList = tempList.Where(recipe => m_recipesMngr.SearchEngine.IsSelected(recipe)).ToList();

            FillRecipeSearchListView();
        }

        /// <summary>
        /// Fyll listan med recept som användaren har sökt efter
        /// </summary> 
        private void FillRecipeSearchListView()
        {
            if (m_recipeList != null)
            {
                ListviewRecipeSearch.Items.Clear();
                foreach (Recipe recipe in m_recipeList)
                {
                    ListviewRecipeSearch.Items.Add(recipe);
                }
            }
        }

        /// <summary>
        /// Knapp för att aktivera visning av receptet
        /// </summary>
        private void ButtonSearchShowRecipe_Click(object sender, RoutedEventArgs e)
        {
            int index = ListviewRecipeSearch.SelectedIndex;
            int ingrediensSize = m_recipeList[index].Ingredients.Count;
            string ingrediens = "Ingrediens:\n";

            for (int i = 0; i < ingrediensSize; i++)
            {
                ingrediens += m_recipeList[index].Ingredients[i].Quantity + " " + m_recipeList[index].Ingredients[i].MeasureType.ToString() + " " +
                    m_recipeList[index].Ingredients[i].Name + "\n";
            }

            MessageBox.Show(string.Format("Namn: {0}\n\nRecepttyp: {1}\n\nPorttionsstorlek: {2}" +
                                          "\n\n{3}",
                m_recipeList[index].Name,
                m_recipeList[index].RecipeType,
                m_recipeList[index].Portions,               
                ingrediens));

        }
    }
}
